package battle;

import battle.controllers.BulletController;
import battle.controllers.CollisionController;
import battle.gameplay.GameScene;
import battle.gameplay.Tank;
import battle.gameplay.TopViewCamera;

import com.jme3.app.SimpleApplication;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.control.PhysicsGhostControl;
import com.jme3.bullet.nodes.PhysicsGhostNode;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.scene.Spatial;
import com.jme3.shadow.PssmShadowRenderer;

public class Battle extends SimpleApplication{
	
	private String gameRef;
	private PlayerType playerType = PlayerType.SinglePlayer;
	protected Tank tank[] = new Tank[8];
	protected GameScene scene;
	protected BulletController bullets;
	protected CollisionController collision;
	protected TopViewCamera topCam;
	protected BulletAppState bulletState;
	protected Spatial bodyModel, headModel;
	protected Material bodyMat, headMat;
	private Vector3f checkPoints[];
	
	public enum PlayerType{
		SinglePlayer, ServerPlayer, ClientPlayer
	};
	
	public Battle(){}
	
	public void simpleInitApp(){
		initSettings();
		initComponents();
		initKeys();
	}
	
	private void initSettings(){
		statsView.removeFromParent();
	}
	
	private void initComponents(){
		bulletState = new BulletAppState();
		bulletState.setThreadingType(BulletAppState.ThreadingType.PARALLEL);
		stateManager.attach(bulletState);
		bullets = new BulletController(assetManager, rootNode, bulletState);
		scene = new GameScene(bulletState);
		rootNode.attachChild(scene.getSpatial());
		bodyModel = assetManager.loadModel("models/body.mesh.xml");
		bodyMat = new Material(assetManager, "Common/MatDefs/Misc/SolidColor.j3md");
		bodyModel.setMaterial(bodyMat);
		headModel = assetManager.loadModel("models/head.mesh.xml");
		headMat = new Material(assetManager, "Common/MatDefs/Misc/SolidColor.j3md");
		headModel.setMaterial(headMat);
		collision = new CollisionController();
		bulletState.getPhysicsSpace().addCollisionGroupListener(collision, PhysicsGhostControl.COLLISION_GROUP_01);
		bulletState.getPhysicsSpace().addCollisionGroupListener(collision, PhysicsGhostControl.COLLISION_GROUP_02);
		bulletState.getPhysicsSpace().addCollisionGroupListener(collision, PhysicsGhostControl.COLLISION_GROUP_03);
		flyCam.setEnabled(false);
		topCam = new TopViewCamera(cam);
		DirectionalLight light = new DirectionalLight();
		light.setDirection(new Vector3f(0.5f, -1f, -0.5f));
		light.setColor(ColorRGBA.White);
		PssmShadowRenderer bsr = new PssmShadowRenderer(assetManager, 768, 1);
		bsr.setDirection(new Vector3f(0.5f, -1f, -0.5f).normalizeLocal());
		rootNode.addLight(light);
		viewPort.addProcessor(bsr);
		
		checkPoints = scene.loadMap("refs/maps/easymap.mp");
		newTank(0);
		scene.createScene(assetManager);
		collision.setCollisionComponents(tank[0], scene);
		topCam.setTarget(tank[0]);
	}
	
	private void initKeys(){
		String tankInputs[] = {"HeadSouth", "HeadEast", "HeadNorth", "HeadWest", "BodySouth", "BodyEast", "BodyNorth", "BodyWest", "Fire"};
		inputManager.addMapping("HeadSouth", new KeyTrigger(KeyInput.KEY_S));
		inputManager.addMapping("HeadEast", new KeyTrigger(KeyInput.KEY_D));
		inputManager.addMapping("HeadNorth", new KeyTrigger(KeyInput.KEY_W));
		inputManager.addMapping("HeadWest", new KeyTrigger(KeyInput.KEY_A));
		inputManager.addMapping("BodySouth", new KeyTrigger(KeyInput.KEY_DOWN));
		inputManager.addMapping("BodyEast", new KeyTrigger(KeyInput.KEY_RIGHT));
		inputManager.addMapping("BodyNorth", new KeyTrigger(KeyInput.KEY_UP));
		inputManager.addMapping("BodyWest", new KeyTrigger(KeyInput.KEY_LEFT));
		inputManager.addMapping("Fire", new KeyTrigger(KeyInput.KEY_SPACE));
//		inputManager.addListener(player, tankInputs);
		String camInputs[] = {"RotateUp", "RotateDown", "RotateLeft", "RotateRight", "ZoomIn", "ZoomOut", "SetDefault"};
		inputManager.addMapping("RotateUp", new KeyTrigger(KeyInput.KEY_PGUP));
		inputManager.addMapping("RotateDown", new KeyTrigger(KeyInput.KEY_PGDN));
		inputManager.addMapping("RotateLeft", new KeyTrigger(KeyInput.KEY_HOME));
		inputManager.addMapping("RotateRight", new KeyTrigger(KeyInput.KEY_END));
		inputManager.addMapping("ZoomIn", new KeyTrigger(KeyInput.KEY_EQUALS));
		inputManager.addMapping("ZoomOut", new KeyTrigger(KeyInput.KEY_MINUS));
		inputManager.addMapping("SetDefault", new KeyTrigger(KeyInput.KEY_BACK));
		inputManager.addListener(topCam, camInputs);
	}
	
	public void newTank(int id){
		tank[id] = new Tank(scene, bullets, bulletState);
		bodyMat.setColor("m_Color", ColorRGBA.Brown);
		headMat.setColor("m_Color", ColorRGBA.Orange);
		tank[id].loadTank(bodyModel, headModel);
	}
	
	public void removeTank(int id){
		bulletState.getPhysicsSpace().remove(tank[id]);
		tank[id].removeFromParent();
		tank[id] = null;
	}
	
	public void attachTank(int id){
		if (!rootNode.hasChild(tank[id]))
			rootNode.attachChild(tank[id]);
	}
	
	public void simpleUpdate(final float tpf){
		topCam.update();
		bullets.update(tpf);
	}
	
	public static void main(String args[]) throws Exception{
		new Battle().start();
	}
}
